{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 数组索引与切片",
   "id": "90afde94db69da22"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 1 重要特性：视图 (View)\n",
    "- 修改切片会直接影响原数组。"
   ],
   "id": "79408e72f9a08e31"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T07:41:33.999474Z",
     "start_time": "2025-08-27T07:41:33.991558Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import numpy as np\n",
    "arr1 = np.arange(10)\n",
    "print(arr1)\n",
    "print('=' * 30)\n",
    "print(arr1[4:6])\n",
    "arr1[4:6] = 520 # 直接修改元数组\n",
    "print(arr1)"
   ],
   "id": "de974e6abc132e97",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3 4 5 6 7 8 9]\n",
      "==============================\n",
      "[4 5]\n",
      "[  0   1   2   3 520 520   6   7   8   9]\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T07:45:57.578466Z",
     "start_time": "2025-08-27T07:45:57.566997Z"
    }
   },
   "cell_type": "code",
   "source": [
    "arr2 = np.arange(20).reshape(4,5)\n",
    "print(arr2) # 4行5列的二维数组\n",
    "print('=' * 30)\n",
    "\n",
    "print(arr2[:1,:])\n",
    "print('=' * 30)\n",
    "print(arr2[:1,:2])\n",
    "arr2[:1,:2] = 520\n",
    "print(arr2)"
   ],
   "id": "dc52f5e1c5815f1e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0  1  2  3  4]\n",
      " [ 5  6  7  8  9]\n",
      " [10 11 12 13 14]\n",
      " [15 16 17 18 19]]\n",
      "==============================\n",
      "[[0 1 2 3 4]]\n",
      "==============================\n",
      "[[0 1]]\n",
      "[[520 520   2   3   4]\n",
      " [  5   6   7   8   9]\n",
      " [ 10  11  12  13  14]\n",
      " [ 15  16  17  18  19]]\n"
     ]
    }
   ],
   "execution_count": 12
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 2. 如果需要副本，应使用 .copy() 方法：\n",
    "- 浅拷贝\n",
    "    - a=b  不能这样赋值，因为a和b相互影响，在内存里a变了b也会发生变化\n",
    "    - a=b[:] 视图操作，一种切片，会创建新的对象a，但是a的数据完全由b保管，他们两个的数据变化是一致的\n",
    "- 深拷贝\n",
    "    - a=b.copy() 复制，a和b互不影响，相当于是重新开辟了一个空间保存b的值，然后让a指向b.copy()"
   ],
   "id": "92ff4ca6845353af"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T07:57:21.870777Z",
     "start_time": "2025-08-27T07:57:21.862011Z"
    }
   },
   "cell_type": "code",
   "source": [
    "arr3 = np.arange(20).reshape(4,5)\n",
    "print(arr3)\n",
    "\n",
    "arr4 = arr3\n",
    "print('arr3的地址是：',id(arr3))\n",
    "print('arr4的地址是:',id(arr4)) # 地址一致，数据共享\n",
    "\n",
    "arr5 = arr3[:]\n",
    "print(arr5)\n",
    "print('arr5的地址是:',id(arr5))\n",
    "print('arr5和arr3是否共享数据:',np.shares_memory(arr5, arr3))\n",
    "\n",
    "# 上述所有的拷贝都是浅拷贝，都是只拷贝了地址，没有单独的拷贝数据，数据是共享的\n",
    "\n",
    "# 修改arr3 ,查看arr4 和 arr5的结果\n",
    "print(arr3[3:,3])\n",
    "arr3[3:,3] = 520\n",
    "print(arr3)\n",
    "print('=' * 30)\n",
    "print(arr4)\n",
    "print('=' * 30)\n",
    "print(arr5)"
   ],
   "id": "81a8395dc3bc8e1e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0  1  2  3  4]\n",
      " [ 5  6  7  8  9]\n",
      " [10 11 12 13 14]\n",
      " [15 16 17 18 19]]\n",
      "arr3的地址是： 1913220584560\n",
      "arr4的地址是: 1913220584560\n",
      "[[ 0  1  2  3  4]\n",
      " [ 5  6  7  8  9]\n",
      " [10 11 12 13 14]\n",
      " [15 16 17 18 19]]\n",
      "arr5的地址是: 1913220588496\n",
      "arr5和arr3是否共享数据: True\n",
      "[18]\n",
      "[[  0   1   2   3   4]\n",
      " [  5   6   7   8   9]\n",
      " [ 10  11  12  13  14]\n",
      " [ 15  16  17 520  19]]\n",
      "==============================\n",
      "[[  0   1   2   3   4]\n",
      " [  5   6   7   8   9]\n",
      " [ 10  11  12  13  14]\n",
      " [ 15  16  17 520  19]]\n",
      "==============================\n",
      "[[  0   1   2   3   4]\n",
      " [  5   6   7   8   9]\n",
      " [ 10  11  12  13  14]\n",
      " [ 15  16  17 520  19]]\n"
     ]
    }
   ],
   "execution_count": 29
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T07:59:17.099674Z",
     "start_time": "2025-08-27T07:59:17.091368Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(arr3)\n",
    "print('=' * 30)\n",
    "arr6 = arr3.copy()\n",
    "print(arr6)\n",
    "print('',np.shares_memory(arr6, arr3))\n",
    "\n",
    "# 修改arr3的值 ，查看arr6是否收到影响\n",
    "arr3[3:,3] = 1314520\n",
    "print('='* 30)\n",
    "print(arr3)\n",
    "print('=' * 30)\n",
    "print(arr6)"
   ],
   "id": "789e3f4dbf093b3e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[  0   1   2   3   4]\n",
      " [  5   6   7   8   9]\n",
      " [ 10  11  12  13  14]\n",
      " [ 15  16  17 520  19]]\n",
      "==============================\n",
      "[[  0   1   2   3   4]\n",
      " [  5   6   7   8   9]\n",
      " [ 10  11  12  13  14]\n",
      " [ 15  16  17 520  19]]\n",
      " False\n",
      "==============================\n",
      "[[      0       1       2       3       4]\n",
      " [      5       6       7       8       9]\n",
      " [     10      11      12      13      14]\n",
      " [     15      16      17 1314520      19]]\n",
      "==============================\n",
      "[[  0   1   2   3   4]\n",
      " [  5   6   7   8   9]\n",
      " [ 10  11  12  13  14]\n",
      " [ 15  16  17 520  19]]\n"
     ]
    }
   ],
   "execution_count": 31
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 3. 布尔索引",
   "id": "d01e3ed6543d2853"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 3.1 当输出的结果需要经过布尔运算（如比较运算）时，即布尔数组索引。\n",
    "- 下面示例返回数组中大于 6 的的所有元素：\n"
   ],
   "id": "5a0dfa47d8abeb3b"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T08:03:19.397764Z",
     "start_time": "2025-08-27T08:03:19.387935Z"
    }
   },
   "cell_type": "code",
   "source": [
    "arr7 = np.arange(10)\n",
    "print(arr7)\n",
    "print('=' * 30)\n",
    "print(arr7[arr7>6])"
   ],
   "id": "e48de651fe83138f",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3 4 5 6 7 8 9]\n",
      "==============================\n",
      "[7 8 9]\n"
     ]
    }
   ],
   "execution_count": 33
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 3.2 实例一：把一维数组进行01化处理，假设这10个数字，我想让大于5的数字变成1，小于5的数字变成0\n",
   "id": "7ccc684426a6d3e1"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T08:06:53.422625Z",
     "start_time": "2025-08-27T08:06:53.415954Z"
    }
   },
   "cell_type": "code",
   "source": [
    "arr8 = np.arange(10)\n",
    "arr8[arr8 <= 5 ] = 0\n",
    "arr8[arr8 > 5] = 1\n",
    "\n",
    "print(arr8)"
   ],
   "id": "2dd125dbe58c04a5",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 0 0 0 0 0 1 1 1 1]\n"
     ]
    }
   ],
   "execution_count": 38
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 3.3 实例二：进行自增量的操作，给大于5个加上520\n",
   "id": "f43af573341978a7"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T08:08:09.108735Z",
     "start_time": "2025-08-27T08:08:09.102044Z"
    }
   },
   "cell_type": "code",
   "source": [
    "arr9 = np.arange(10)\n",
    "arr9[arr9 > 5] += 520\n",
    "print(arr9)"
   ],
   "id": "792df67e1267d4a0",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[  0   1   2   3   4   5 526 527 528 529]\n"
     ]
    }
   ],
   "execution_count": 39
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 3.3 二维数组的操作",
   "id": "efdc95210a1bf257"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T08:16:31.188992Z",
     "start_time": "2025-08-27T08:16:31.180309Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 把第3列大于5的行筛选出来，并重新赋值为520\n",
    "arr10 = np.arange(1,21).reshape(4,5)\n",
    "print(arr10)\n",
    "print('=' * 30)\n",
    "print(arr10[:,3]) # 找出第三列\n",
    "# print('=' * 30)\n",
    "# print(arr10[:,3][arr10[:,3]>5])\n",
    "# print('=' * 30)\n",
    "# arr10[:,3][arr10[:,3]>5] = 520\n",
    "# print(arr10)\n",
    "\n",
    "flag = arr10[:,3] > 5 # 找出第三列中大于5的数\n",
    "print(flag)\n",
    "arr10[:,3][flag] = 520 # 在第三列中修改的\n",
    "print(arr10)"
   ],
   "id": "ee29d70f180749a9",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3  4  5]\n",
      " [ 6  7  8  9 10]\n",
      " [11 12 13 14 15]\n",
      " [16 17 18 19 20]]\n",
      "==============================\n",
      "[ 4  9 14 19]\n",
      "[False  True  True  True]\n",
      "[[  1   2   3   4   5]\n",
      " [  6   7   8 520  10]\n",
      " [ 11  12  13 520  15]\n",
      " [ 16  17  18 520  20]]\n"
     ]
    }
   ],
   "execution_count": 54
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T08:24:42.028983Z",
     "start_time": "2025-08-27T08:24:42.020537Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 把第三列大于5的元素替换成520 # 直接在数组中修改第三列\n",
    "arr11 = np.arange(1,21).reshape(4,5)\n",
    "print(arr11)\n",
    "print('=' * 30)\n",
    "\n",
    "# 找到第三列\n",
    "print(arr11[:,3])\n",
    "print('=' * 30)\n",
    "\n",
    "print(arr11[arr11[:,3] > 5])  # 得到了 9 14 19 所在的行数\n",
    "print('=' * 30)\n",
    "print(arr11[arr11[:,3] > 5,3]) #  得到了 9 14 19 所在的行数 ，也得到了第三列\n",
    "print('=' * 30)\n",
    "arr11[arr11[:,3] > 5,3] = 520\n",
    "print(arr11)\n"
   ],
   "id": "d5a3bc361b1445eb",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3  4  5]\n",
      " [ 6  7  8  9 10]\n",
      " [11 12 13 14 15]\n",
      " [16 17 18 19 20]]\n",
      "==============================\n",
      "[ 4  9 14 19]\n",
      "==============================\n",
      "[[ 6  7  8  9 10]\n",
      " [11 12 13 14 15]\n",
      " [16 17 18 19 20]]\n",
      "==============================\n",
      "[ 9 14 19]\n",
      "==============================\n",
      "[[  1   2   3   4   5]\n",
      " [  6   7   8 520  10]\n",
      " [ 11  12  13 520  15]\n",
      " [ 16  17  18 520  20]]\n"
     ]
    }
   ],
   "execution_count": 61
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T08:40:09.071498Z",
     "start_time": "2025-08-27T08:40:09.064623Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 二维数组\n",
    "arr12 = np.array([\n",
    "    [10,20,30],\n",
    "    [40,10,20],\n",
    "    [50,5,60]\n",
    "])\n",
    "# 找出大于25的数字\n",
    "flag = arr12 > 25\n",
    "print(arr12[flag])"
   ],
   "id": "c78dda8f5edac419",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[30 40 50 60]\n"
     ]
    }
   ],
   "execution_count": 62
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T08:43:33.918436Z",
     "start_time": "2025-08-27T08:43:33.908639Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 条件组合，找出偶数或者小于7的数字\n",
    "arr13 = np.arange(1,21)\n",
    "print(arr13)\n",
    "print('=' * 30)\n",
    "flag = (arr13 % 2 == 0) | (arr13 < 7)\n",
    "print(flag)\n",
    "print('=' * 30)\n",
    "print(arr13[flag])"
   ],
   "id": "7fd5e231d1bba95e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20]\n",
      "==============================\n",
      "[ True  True  True  True  True  True False  True False  True False  True\n",
      " False  True False  True False  True False  True]\n",
      "==============================\n",
      "[ 1  2  3  4  5  6  8 10 12 14 16 18 20]\n"
     ]
    }
   ],
   "execution_count": 65
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 4. 神奇索引\n",
    "- 使用整数数组进行数据索引"
   ],
   "id": "fab265d78c30662d"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T08:49:42.248936Z",
     "start_time": "2025-08-27T08:49:42.240597Z"
    }
   },
   "cell_type": "code",
   "source": [
    "arr14 = np.array([\n",
    "    3,6,7,9,5,2,1,4\n",
    "])\n",
    "print(arr14)\n",
    "print('=' * 30)\n",
    "# 找出下标是2 3 5的元素\n",
    "arr15 = arr14[[2,3,5]]\n",
    "print(arr15)\n"
   ],
   "id": "6e47c871a32c2827",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3 6 7 9 5 2 1 4]\n",
      "==============================\n",
      "[7 9 2]\n"
     ]
    }
   ],
   "execution_count": 71
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T08:57:36.656733Z",
     "start_time": "2025-08-27T08:57:36.648704Z"
    }
   },
   "cell_type": "code",
   "source": [
    "arr16 =  np.arange(32).reshape((8,4))\n",
    "print(arr16)\n",
    "print('-'*30)\n",
    "# 取第1行第1列，第5行第3列，第7行第1列，第2行第2列\n",
    "print(arr16[[0,4,6,1],[0,2,0,1]])"
   ],
   "id": "dc54345b97da53fa",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0  1  2  3]\n",
      " [ 4  5  6  7]\n",
      " [ 8  9 10 11]\n",
      " [12 13 14 15]\n",
      " [16 17 18 19]\n",
      " [20 21 22 23]\n",
      " [24 25 26 27]\n",
      " [28 29 30 31]]\n",
      "------------------------------\n",
      "[ 0 18 24  5]\n"
     ]
    }
   ],
   "execution_count": 80
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T08:56:55.163600Z",
     "start_time": "2025-08-27T08:56:55.156428Z"
    }
   },
   "cell_type": "code",
   "source": [
    "arr17 =  np.arange(32).reshape((8,4))\n",
    "print(arr17)\n",
    "print('=' * 30)\n",
    "# 获取所有行的，第一列和第二列\n",
    "print(arr17[:,[0,1]])"
   ],
   "id": "f8e31cadaeffdc94",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0  1  2  3]\n",
      " [ 4  5  6  7]\n",
      " [ 8  9 10 11]\n",
      " [12 13 14 15]\n",
      " [16 17 18 19]\n",
      " [20 21 22 23]\n",
      " [24 25 26 27]\n",
      " [28 29 30 31]]\n",
      "==============================\n",
      "[[ 0  1]\n",
      " [ 4  5]\n",
      " [ 8  9]\n",
      " [12 13]\n",
      " [16 17]\n",
      " [20 21]\n",
      " [24 25]\n",
      " [28 29]]\n"
     ]
    }
   ],
   "execution_count": 79
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-27T09:10:31.002437Z",
     "start_time": "2025-08-27T09:10:30.986673Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 实例：获取数组中最大的前N个数\n",
    "np.random.seed(6)\n",
    "arr18 = np.random.randint(1,10000,10) # 生成一个长度wield10的随机数组，元素范围1-10000之间\n",
    "print(arr18)\n",
    "print('=' * 30)\n",
    "\n",
    "# 数组.argsort()会返回排序后的下标\n",
    "# 取最大值对应的3个下标，因为默认升序，所以取最后三个\n",
    "index = arr18.argsort()\n",
    "print(index) # 排序后的下标\n",
    "# print('=' * 30)\n",
    "# print(index[:-4:-1])\n",
    "# print('=' * 30)\n",
    "# print(arr18[index[:-4:-1]])\n",
    "\n",
    "print('=' * 30)\n",
    "print(index[-3:])\n",
    "print('=' * 30)\n",
    "print(arr18[index[-3:]])\n"
   ],
   "id": "b3bc927e793462a6",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2762 8420 4715 8528 9041 6463 5402 7244 4123 2544]\n",
      "==============================\n",
      "[9 0 8 2 6 5 7 1 3 4]\n",
      "==============================\n",
      "[1 3 4]\n",
      "==============================\n",
      "[8420 8528 9041]\n"
     ]
    }
   ],
   "execution_count": 122
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
